﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text;

namespace Utils
{
    public static class EnumUtil
    {
        /// <summary>
        /// 获取枚举
        /// </summary>
        /// <param name="enumeration"></param>
        /// <returns></returns>
        public static string GetDescription(this Enum enumeration)
        {
            return enumeration.GetAttribute<DescriptionAttribute>()?.Description ?? enumeration.ToString();
        }

        public static IDictionary<string, (long Value, string Description)> GetEnumDict<T>() where T : Enum
        {
            return typeof(T).GetFields(BindingFlags.Public | BindingFlags.Static)
                .ToDictionary(e => e.Name, e => (Convert.ToInt64(e.GetValue(null)), e.GetCustomAttribute<DescriptionAttribute>()?.Description));
        }

        public static IDictionary<long, string> GetDictionary<T>() where T : Enum
        {
            return typeof(T).GetFields(BindingFlags.Public | BindingFlags.Static)
                .ToDictionary(t => Convert.ToInt64(t.GetValue(null)), t => t.GetCustomAttribute<DescriptionAttribute>()?.Description);
        }

        public static (string Name, long Value, string Description)[] GetEnums<T>() where T : Enum
        {
            return GetEnums(typeof(T));
        }

        public static (string Name, long Value, string Description)[] GetEnums(Type type)
        {
            return type.GetFields(BindingFlags.Public | BindingFlags.Static)
                .Select(e => (e.Name, Convert.ToInt64(e.GetValue(null)), e.GetCustomAttribute<DescriptionAttribute>()?.Description)).ToArray();
        }

        public static T GetAttribute<T>(this Enum enumeration) where T : Attribute
        {
            Type type = enumeration.GetType();
            return type.GetField(enumeration.ToString(), BindingFlags.Public | BindingFlags.Static).GetCustomAttribute<T>();
        }

        /// <summary>
        /// 位与
        /// </summary>
        /// <param name="e"></param>
        /// <param name="flag"></param>
        /// <returns></returns>
        public static bool HasFlag(this Enum e, Enum flag)
        {
            return HasFlag(e, Convert.ToInt32(flag));
        }

        /// <summary>
        /// 位与
        /// </summary>
        /// <param name="e"></param>
        /// <param name="flag"></param>
        /// <returns></returns>
        public static bool HasFlag(this Enum e, int flag)
        {
            return (Convert.ToInt32(e) & flag) != 0;
        }
    }
}
